function maxSendRequest(urls, max, callback) {
  let allUrls = [...urls],
    i = 0,
    fetchArr = [];

  function doFetch() {
    // 处理边界的情况
    if (i === allUrls.length) {
      return Promise.resolve();
    }
    //每次调用出去 一个 url， 放入fetch中
    let one = fetch(allUrls[i++]);
    // 将此promise的状态保存在fetchArr中， 执行完之后 从数组中删除。
    let result = one.then(() => fetchArr.splice(fetchArr.indexOf(result), 1));
    result.push(fetchArr);

    // 数量不够就重复调用doFetch， 够了的话就比较
    let p = Promise.resolve();
    if (fetchArr.length >= max) {
      p = Promise.race(fetchArr);
    }
    return p.then(() => doFetch())
  }
  // 最后用all 处理剩余数组中的，等处理完再执行callback
  return doFetch().then(() => Promise.all(fetchArr)).then(() => {
    callback();
  })
}

function multiRequest(urls = [], maxNum) {
  // 请求总数量
  const len = urls.length;
  // 根据请求数量创建一个数组来保存请求的结果
  const result = new Array(len).fill(false);
  // 当前完成的数量
  let count = 0;

  return new Promise((resolve, reject) => {
    // 请求maxNum个
    while (count < maxNum) {
      next();
    }
    function next() {
      let current = count++;
      // 处理边界条件
      if (current >= len) {
        // 请求全部完成就将promise置为成功状态, 然后将result作为promise值返回
        !result.includes(false) && resolve(result);
        return;
      }
      const fetch = urls[current];
      console.log(`开始 ${current}`, new Date().toLocaleString());
      fetch()
        .then((res) => {
          // 保存请求结果
          result[current] = res;
          console.log(`完成 ${current}`, new Date().toLocaleString());
          // 请求没有全部完成, 就递归
          if (current < len) {
            next();
          }
        })
        .catch((err) => {
          console.log(`结束 ${current}`, new Date().toLocaleString());
          result[current] = err;
          // 请求没有全部完成, 就递归
          if (current < len) {
            next();
          }
        });
    }
  });
}

const fetch1 = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(1);
    }, (Math.random() + 1) * 1000);
  })
}

const fetch2 = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(2);
    }, (Math.random() + 1) * 1000);
  })
}

const fetch3 = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(3);
    }, (Math.random() + 1) * 1000);
  })
}


multiRequest([fetch1, fetch2, fetch3], 2).then(res => {
  console.log(res)
})